﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Parser.LanguageCharacteristics`3
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Collections.Generic;
using System.Linq;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;

namespace System.Web.Razor.Parser
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Provides methods that define the behavior of a Razor code language.</summary>
  /// <typeparam name="TTokenizer">The type of the code tokenizer for the Razor language.</typeparam>
  /// <typeparam name="TSymbol">The type for the language symbol.</typeparam>
  /// <typeparam name="TSymbolType">The enumeration type for the language symbol.</typeparam>
  public abstract class LanguageCharacteristics<TTokenizer, TSymbol, TSymbolType>
    where TTokenizer : System.Web.Razor.Tokenizer.Tokenizer<TSymbol, TSymbolType>
    where TSymbol : SymbolBase<TSymbolType>
  {
    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Gets the actual symbol for the given language symbol type.</summary>
    /// <returns>The actual symbol for the given language symbol type.</returns>
    /// <param name="type">The language symbol type to get.</param>
    public abstract string GetSample(TSymbolType type);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Creates a Razor code language tokenizer for the specified source document.</summary>
    /// <returns>A Razor code language tokenizer for the specified source document.</returns>
    /// <param name="source">The source document.</param>
    public abstract TTokenizer CreateTokenizer(ITextDocument source);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Returns the opposite bracket symbol for the specified bracket symbol.</summary>
    /// <returns>The opposite bracket symbol for the specified bracket symbol.</returns>
    /// <param name="bracket">The bracket symbol to flip.</param>
    public abstract TSymbolType FlipBracket(TSymbolType bracket);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Creates a code language symbol with the specified source location as the start marker.</summary>
    /// <returns>The symbol for the code language.</returns>
    /// <param name="location">The source location as the start marker.</param>
    public abstract TSymbol CreateMarkerSymbol(SourceLocation location);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Splits the specified string into tokens.</summary>
    /// <returns>The collection of token.</returns>
    /// <param name="content">The string to tokenize.</param>
    public virtual IEnumerable<TSymbol> TokenizeString(string content) => this.TokenizeString(SourceLocation.Zero, content);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Splits the specified string into tokens.</summary>
    /// <returns>The collection of token.</returns>
    /// <param name="start">The source location as the start marker for the tokenizer.</param>
    /// <param name="input">The string to tokenize.</param>
    public virtual IEnumerable<TSymbol> TokenizeString(
      SourceLocation start,
      string input)
    {
      using (SeekableTextReader reader = new SeekableTextReader(input))
      {
        TTokenizer tok = this.CreateTokenizer((ITextDocument) reader);
        TSymbol symbol;
        while ((object) (symbol = tok.NextSymbol()) != null)
        {
          symbol.OffsetStart(start);
          yield return symbol;
        }
        tok = default (TTokenizer);
      }
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a whitespace type.</summary>
    /// <returns>true if the symbol is a whitespace type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsWhiteSpace(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.WhiteSpace);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a new line type.</summary>
    /// <returns>true if the symbol is a new line type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsNewLine(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.NewLine);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is an identifier type.</summary>
    /// <returns>true if the symbol is an identifier type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsIdentifier(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.Identifier);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a keyword type.</summary>
    /// <returns>true if the symbol is a keyword type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsKeyword(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.Keyword);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a transition type.</summary>
    /// <returns>true if the symbol is a transition type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsTransition(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.Transition);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a comment start type.</summary>
    /// <returns>true if the symbol is a comment start type; otherwise, false. </returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsCommentStart(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.CommentStart);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a comment star type.</summary>
    /// <returns>true if the symbol is a comment star type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsCommentStar(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.CommentStar);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is a comment body type.</summary>
    /// <returns>true if the symbol is a comment body type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsCommentBody(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.CommentBody);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is an unknown type.</summary>
    /// <returns>true if the symbol is an unknown type; otherwise, false.</returns>
    /// <param name="symbol">The symbol to check.</param>
    public virtual bool IsUnknown(TSymbol symbol) => this.IsKnownSymbolType(symbol, KnownSymbolType.Unknown);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol type is a known symbol type.</summary>
    /// <returns>true if the symbol type is a known symbol type; otherwise, false.</returns>
    /// <param name="symbol">The symbol whose type is to be checked.</param>
    /// <param name="type">The known type of the symbol.</param>
    public virtual bool IsKnownSymbolType(TSymbol symbol, KnownSymbolType type) => (object) symbol != null && object.Equals((object) symbol.Type, (object) this.GetKnownSymbolType(type));

    /// <summary>Splits the content of the code language symbol at the specified index.</summary>
    /// <returns>A tuple of code language symbol.</returns>
    /// <param name="symbol">The symbol whose content is to be splitted.</param>
    /// <param name="splitAt">The index where the split occurs.</param>
    /// <param name="leftType">The enumeration type for the language symbol.</param>
    public virtual Tuple<TSymbol, TSymbol> SplitSymbol(
      TSymbol symbol,
      int splitAt,
      TSymbolType leftType)
    {
      TSymbol symbol1 = this.CreateSymbol(symbol.Start, symbol.Content.Substring(0, splitAt), leftType, Enumerable.Empty<RazorError>());
      TSymbol symbol2 = default (TSymbol);
      if (splitAt < symbol.Content.Length)
        symbol2 = this.CreateSymbol(SourceLocationTracker.CalculateNewLocation(symbol.Start, symbol1.Content), symbol.Content.Substring(splitAt), symbol.Type, symbol.Errors);
      return Tuple.Create<TSymbol, TSymbol>(symbol1, symbol2);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Gets the specific language symbol type for the given symbol type.</summary>
    /// <returns>The specific language symbol type for the given symbol type.</returns>
    /// <param name="type">The symbol type to get.</param>
    public abstract TSymbolType GetKnownSymbolType(KnownSymbolType type);

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Determines whether the symbol is an unknown type.</summary>
    /// <returns>true if the symbol is an unknown type; otherwise, false.</returns>
    /// <param name="type">The known type of the symbol.</param>
    public virtual bool KnowsSymbolType(KnownSymbolType type) => type == KnownSymbolType.Unknown || !object.Equals((object) this.GetKnownSymbolType(type), (object) this.GetKnownSymbolType(KnownSymbolType.Unknown));

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code. Creates a code language symbol with the specified source location with the specified source location as the start marker.</summary>
    /// <returns>The symbol for the code language.</returns>
    /// <param name="location">The source location as the start marker.</param>
    /// <param name="content">The content.</param>
    /// <param name="type">The enumeration type for the language symbol.</param>
    /// <param name="errors">The collection of error.</param>
    protected abstract TSymbol CreateSymbol(
      SourceLocation location,
      string content,
      TSymbolType type,
      IEnumerable<RazorError> errors);
  }
}
